package cn.h8k.hj212.codec.impl;

import cn.h8k.hj212.codec.Hj212EntityCodec;
import cn.h8k.hj212.codec.Hj212Validator;
import cn.h8k.hj212.constant.Hj212Constants;
import cn.h8k.hj212.entity.Hj212CpGroup;
import cn.h8k.hj212.entity.Hj212CpItem;
import cn.h8k.hj212.entity.Hj212Data;
import cn.h8k.hj212.entity.Hj212Header;
import cn.h8k.hj212.entity.Hj212Message;

import java.util.ArrayList;
import java.util.List;

/**
 * HJ212协议实体类编解码器默认实现
 * 可被继承以自定义实体编解码行为
 */
public class DefaultHj212EntityCodec implements Hj212EntityCodec {
    
    private final Hj212Validator validator;
    
    /**
     * 默认构造函数，使用默认校验器
     */
    public DefaultHj212EntityCodec() {
        this.validator = new DefaultHj212Validator();
    }
    
    /**
     * 自定义构造函数
     * @param validator 校验器
     */
    public DefaultHj212EntityCodec(Hj212Validator validator) {
        this.validator = validator;
    }
    
    @Override
    public String encode(Hj212Message message) {
        if (message == null || message.getData() == null) {
            throw new IllegalArgumentException("消息或数据不能为空");
        }
        
        // 构建数据部分
        StringBuilder dataBuilder = new StringBuilder();
        Hj212Data data = message.getData();
        
        // 添加基本字段
        if (data.getQn() != null) {
            dataBuilder.append(Hj212Constants.QN).append(Hj212Constants.KEY_VALUE_SEPARATOR)
                .append(data.getQn()).append(Hj212Constants.FIELD_SEPARATOR);
        }
        if (data.getSt() != null) {
            dataBuilder.append(Hj212Constants.ST).append(Hj212Constants.KEY_VALUE_SEPARATOR)
                .append(data.getSt()).append(Hj212Constants.FIELD_SEPARATOR);
        }
        if (data.getCn() != null) {
            dataBuilder.append(Hj212Constants.CN).append(Hj212Constants.KEY_VALUE_SEPARATOR)
                .append(data.getCn()).append(Hj212Constants.FIELD_SEPARATOR);
        }
        if (data.getPw() != null) {
            dataBuilder.append(Hj212Constants.PW).append(Hj212Constants.KEY_VALUE_SEPARATOR)
                .append(data.getPw()).append(Hj212Constants.FIELD_SEPARATOR);
        }
        if (data.getMn() != null) {
            dataBuilder.append(Hj212Constants.MN).append(Hj212Constants.KEY_VALUE_SEPARATOR)
                .append(data.getMn()).append(Hj212Constants.FIELD_SEPARATOR);
        }
        if (data.getFlag() != null) {
            dataBuilder.append(Hj212Constants.FLAG).append(Hj212Constants.KEY_VALUE_SEPARATOR)
                .append(data.getFlag()).append(Hj212Constants.FIELD_SEPARATOR);
        }
        
        // 添加CP数据
        if (data.getCpGroups() != null && !data.getCpGroups().isEmpty()) {
            dataBuilder.append(Hj212Constants.CP).append(Hj212Constants.KEY_VALUE_SEPARATOR)
                .append(Hj212Constants.GROUP_SEPARATOR);
            boolean firstGroup = true;
            
            for (Hj212CpGroup cpGroup : data.getCpGroups()) {
                if (!firstGroup) {
                    dataBuilder.append(Hj212Constants.FIELD_SEPARATOR);
                }
                
                boolean firstItem = true;
                for (Hj212CpItem item : cpGroup.getItems()) {
                    if (!firstItem) {
                        dataBuilder.append(Hj212Constants.ITEM_SEPARATOR);
                    }
                    dataBuilder.append(item.getName()).append(Hj212Constants.KEY_VALUE_SEPARATOR)
                        .append(item.getValue());
                    firstItem = false;
                }
                firstGroup = false;
            }
            dataBuilder.append(Hj212Constants.GROUP_SEPARATOR);
        }
        
        String dataString = dataBuilder.toString();
        
        // 构建完整协议字符串
        StringBuilder result = new StringBuilder();
        result.append(Hj212Constants.HEAD);
        result.append(String.format(Hj212Constants.LENGTH_FORMAT, dataString.length()));
        result.append(dataString);
        result.append(validator.calculateCrc(dataString).toUpperCase());
        result.append(Hj212Constants.LINE_ENDING);
        
        return result.toString();
    }
    
    @Override
    public Hj212Message decode(String data) {
        if (data == null || data.trim().isEmpty()) {
            throw new IllegalArgumentException("数据不能为空");
        }
        
        // 解析头部
        Hj212Header header = new Hj212Header();
        header.setHead(data.substring(0, 2));
        header.setLength(data.substring(2, 6));
        
        // 解析CRC
        String crc = data.substring(data.length() - 6, data.length() - 2);
        
        // 解析数据部分
        int length = Integer.parseInt(data.substring(2, 6));
        String body = data.substring(6, 6 + length);
        
        // 数据长度验证
        if (!validator.validateLength(body, length)) {
            throw new IllegalArgumentException(Hj212Constants.ERROR_LENGTH_VALIDATION);
        }
        
        // CRC校验
        if (!validator.validateCrc(body, crc)) {
            throw new IllegalArgumentException(Hj212Constants.ERROR_CRC_VALIDATION);
        }
        
        // 解析数据内容
        Hj212Data messageData = parseDataBody(body);
        
        // 构建消息实体
        Hj212Message message = new Hj212Message();
        message.setHeader(header);
        message.setData(messageData);
        message.setCrc(crc);
        
        return message;
    }
    
    /**
     * 解析数据体
     * @param body 数据体字符串
     * @return 解析后的数据实体
     */
    private Hj212Data parseDataBody(String body) {
        Hj212Data data = new Hj212Data();
        List<Hj212CpGroup> cpGroups = new ArrayList<>();
        
        String[] parts = body.split(Hj212Constants.GROUP_SEPARATOR);
        if (parts.length > 1) {
            // 处理非CP部分
            String mainPart = parts[0];
            String[] mainItems = mainPart.split(Hj212Constants.FIELD_SEPARATOR);
            for (String item : mainItems) {
                if (item.isEmpty() || !item.contains(Hj212Constants.KEY_VALUE_SEPARATOR)) continue;
                
                String[] kv = item.split(Hj212Constants.KEY_VALUE_SEPARATOR, 2);
                if (kv.length == 2) {
                    switch (kv[0]) {
                        case Hj212Constants.QN:
                            data.setQn(kv[1]);
                            break;
                        case Hj212Constants.ST:
                            data.setSt(kv[1]);
                            break;
                        case Hj212Constants.CN:
                            data.setCn(kv[1]);
                            break;
                        case Hj212Constants.PW:
                            data.setPw(kv[1]);
                            break;
                        case Hj212Constants.MN:
                            data.setMn(kv[1]);
                            break;
                        case Hj212Constants.FLAG:
                            data.setFlag(kv[1]);
                            break;
                    }
                }
            }
            
            // 处理CP部分
            if (parts.length > 1 && parts[1].length() > 0) {
                String cpPart = parts[1];
                String[] cpGroupsStr = cpPart.split(Hj212Constants.FIELD_SEPARATOR);
                
                for (int i = 0; i < cpGroupsStr.length; i++) {
                    String cpGroupStr = cpGroupsStr[i];
                    if (cpGroupStr.isEmpty()) continue;
                    
                    Hj212CpGroup cpGroup = new Hj212CpGroup(i);
                    String[] cpItems = cpGroupStr.split(Hj212Constants.ITEM_SEPARATOR);
                    
                    for (String cpItem : cpItems) {
                        if (cpItem.isEmpty() || !cpItem.contains(Hj212Constants.KEY_VALUE_SEPARATOR)) continue;
                        
                        String[] kv = cpItem.split(Hj212Constants.KEY_VALUE_SEPARATOR, 2);
                        if (kv.length == 2) {
                            // 尝试解析数值类型
                            Object value = parseValue(kv[1]);
                            
                            Hj212CpItem item = new Hj212CpItem(kv[0], value);
                            cpGroup.addItem(item);
                        }
                    }
                    
                    cpGroups.add(cpGroup);
                }
            }
        }
        
        data.setCpGroups(cpGroups);
        return data;
    }
    
    /**
     * 保护方法：子类可重写以自定义值的解析
     * @param valueStr 值字符串
     * @return 解析后的值对象
     */
    protected Object parseValue(String valueStr) {
        try {
            if (valueStr.contains(Hj212Constants.DECIMAL_POINT)) {
                return Double.parseDouble(valueStr);
            } else {
                return valueStr;
            }
        } catch (NumberFormatException e) {
            return valueStr;
        }
    }
} 